import os
import yaml

from omegaconf import OmegaConf

from zs_config.common import iterate_load_paths


# Not using the built-in 'oc.env' resolver since the name may be confusing
OmegaConf.register_new_resolver('ENV', lambda x, default='':
                                            os.environ.get(x, default))

_local_search_paths = [
    '/etc/zs_config',
    f'{os.environ.get("HOME", "")}/zs_config',
    '.',
    '../'
]

_local_fs_bootstrap_cfg_files = [
    'bootstrap_dir/bootstrap_cfg.yaml',
    'bootstrap_cfg.yaml',
]

cloud_cfg_file = './cloud_config.yaml'

if os.path.exists(cloud_cfg_file):
    with open(cloud_cfg_file, "r", encoding="utf-8") as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
    _local_search_paths = [config['ZS_CONFIG_OVERRIDE_SEARCH_PATH']]
    oss_env = config['OSS_ENV']
    for key, value in oss_env.items():
        os.environ[key] = value

def get_bootstrap_cfg():
    """
    If override path is defined in the environment, it is used as the
    only search path. This should be able to provide enough
    flexibility for testing purposes.

    For example, if ZS_CONFIG_OVERRIDE_SEARCH_PATH is "/foo" in the
    environment, zs_config will look for the bootstrap config file
    "/foo/bootstrap_dir/bootstrap_cfg.yaml". The bootstrap config file
    can then define any schema directories and config directories or
    even different schema/config loaders etc. as needed.
    """
    global _local_search_paths
    override_path = os.environ.get('ZS_CONFIG_OVERRIDE_SEARCH_PATH', None)
    override_path = 'air_web/air_wds/zshield/bin/ruleng/air_config';
    if override_path is not None:
        print(f'WARNING: Using search path override ({override_path})')
        _local_search_paths = [override_path] + _local_search_paths
    bootstrap_cfg = None
    for lpath in iterate_load_paths(_local_search_paths,
                                    _local_fs_bootstrap_cfg_files):
        if os.path.isfile(lpath):
            with open(lpath) as fin:
                try:
                    bootstrap_cfg = OmegaConf.load(fin)
                    break
                except Exception as e:
                    msg = f'Invalid local bootstrap config: {str(e)}'
                    raise Exception(msg) from None

        elif False:
            # Try other methods
            pass

    if bootstrap_cfg is None:
        raise Exception('Cannot find bootstrap config')

    search_cfg = {
        'common': {
            'local': {
                'search_paths': _local_search_paths
            }
        }
    }
    # If common.local.search_paths is defined in bootstrap cfg, it will
    # override the one here.
    return OmegaConf.merge(search_cfg, bootstrap_cfg)

